package com.dlyk.config.handler;

import com.dlyk.exception.PasswordVerifyFailException;
import com.dlyk.result.CodeEnum;
import com.dlyk.result.R;
import org.springframework.dao.DataAccessException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理器
 */
// AOP，拦截使用了@Controller注解的Controller类中的所有方法
// @ControllerAdvice

// AOP，拦截使用了@RestController注解的Controller类中的所有方法
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 异常处理的方法
     */
    @ExceptionHandler(value = Exception.class)
    public R handException(Exception e) {
        // 在控制台打印异常堆栈信息
        e.printStackTrace();

        // 返回给前端数据
        return R.FAIL(e.getMessage());
    }

    /**
     * 异常的精确匹配，先精确匹配，匹配不到了，就找父类的异常处理
     *
     * DataAccessException：数据访问异常
     *
     * 例如：从数据库中删除某条数据的时候，该数据的某个字段被引用做外键，并且使用的是拒绝策略
     */
    @ExceptionHandler(value = DataAccessException.class)
    public R dataAccessException(Exception e) {
        // 在控制台打印异常堆栈信息
        e.printStackTrace();

        // 返回给前端数据
        return R.FAIL(CodeEnum.DATA_ACCESS_EXCEPTION);
    }

    /**
     * 密码验证未通过异常处理器
     */
    @ExceptionHandler(value = PasswordVerifyFailException.class)
    public R passwordVerifyFailException(PasswordVerifyFailException e) {
        // 在控制台打印异常堆栈信息
        e.printStackTrace();

        // 返回给前端数据
        return R.FAIL(CodeEnum.PASSWORD_VERIFY_FAIL_EXCEPTION);
    }

    /**
     * 访问拒绝异常处理器（权限不足时的处理）
     */
    @ExceptionHandler(value = AccessDeniedException.class)
    public R accessDeniedException(AccessDeniedException e) {
        // 在控制台打印异常堆栈信息
        e.printStackTrace();

        // 返回给前端数据
        return R.FAIL(CodeEnum.ACCESS_DENIED);
    }

}

